package kz.pompei.ifacer.main.toolbar;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JToolBar;

import kz.pompei.ifacer.grot.GrotPanel;
import kz.pompei.ifacer.grot.acts.Act;
import kz.pompei.ifacer.main.GrotTabPanel;
import kz.pompei.ifacer.main.KeyAcceptor;
import kz.pompei.ifacer.model.widgets.Widget;
import kz.pompei.ifacer.model.widgets.WidgetRect;
import kz.pompei.ifacer.util.Handler;
import kz.pompei.ifacer.visio.WidgetProp;

public class BottomToolBar {
  public final JToolBar source = new JToolBar("BottomToolBar");
  private final GrotTabPanel grotTabPanel;
  
  class Dot {
    final JLabel label;
    final JTextField textField;
    
    public Dot(JLabel label, JTextField textField) {
      this.label = label;
      this.textField = textField;
    }
  }
  
  private final Map<WidgetProp, Dot> fields = new HashMap<>();
  
  public BottomToolBar(GrotTabPanel grotTabPanel) {
    this.grotTabPanel = grotTabPanel;
    for (final WidgetProp f : WidgetProp.values()) {
      JLabel b = new JLabel(f.name().toLowerCase() + ":");
      source.add(b);
      
      JTextField s = new JTextField();
      s.setMaximumSize(new Dimension(60, 60));
      source.add(s);
      b.setLabelFor(s);
      b.setEnabled(false);
      source.addSeparator();
      fields.put(f, new Dot(b, s));
      
      s.addKeyListener(new KeyAdapter() {
        final KeyAcceptor enter = KeyAcceptor.parse("Enter");
        
        @Override
        public void keyPressed(KeyEvent e) {
          if (enter.accept(e)) {
            enterPressedOn(f);
          }
        }
      });
    }
    
    this.grotTabPanel.updates.add(new Handler() {
      @Override
      public void handle() throws Exception {
        update();
      }
    });
  }
  
  private void update() throws Exception {
    GrotPanel grot = grotTabPanel.getActiveGrot();
    if (grot == null) {
      disableAll();
      return;
    }
    if (grot.selectedUuids.size() != 1) {
      disableAll();
      return;
    }
    
    Widget widget = grot.actContainer.storage.getWidgetByUuid(grot.selectedUuids.iterator().next());
    
    Graphics2D g = grot.newG();
    Rectangle r = grot.visio.getWidgetBound(g, widget);
    g.dispose();
    
    setValue(WidgetProp.LEFT, r.x, true);
    setValue(WidgetProp.TOP, r.y, true);
    setValue(WidgetProp.WIDTH, r.width, widget instanceof WidgetRect);
    setValue(WidgetProp.HEIGHT, r.height, widget instanceof WidgetRect);
    
    setValue(WidgetProp.RIGHT, r.x + r.width, true);
    setValue(WidgetProp.BOTTOM, r.y + r.height, true);
  }
  
  private void disableAll() {
    for (WidgetProp f : WidgetProp.values()) {
      setValue(f, 0, false);
    }
  }
  
  private void setValue(WidgetProp field, int value, boolean enabled) {
    Dot dot = fields.get(field);
    dot.label.setEnabled(enabled);
    dot.textField.setText("" + value);
    dot.textField.setEditable(enabled);
  }
  
  private int getValue(WidgetProp field) {
    String txt = fields.get(field).textField.getText();
    if (txt == null) return 0;
    txt = txt.trim();
    if (txt.length() == 0) return 0;
    try {
      return Integer.parseInt(txt);
    } catch (NumberFormatException e) {
      return 0;
    }
    
  }
  
  private void enterPressedOn(WidgetProp field) {
    try {
      enterPressedOnInner(field);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  
  private void enterPressedOnInner(WidgetProp field) throws Exception {
    GrotPanel grot = grotTabPanel.getActiveGrot();
    if (grot == null) return;
    if (grot.selectedUuids.size() != 1) return;
    
    Widget widget = grot.actContainer.storage.getWidgetByUuid(grot.selectedUuids.iterator().next());
    
    int value = getValue(field);
    
    Graphics2D g = grot.newG();
    Act act = grot.visio.setProperty(g, widget, field, value);
    g.dispose();
    
    if (act == null) return;
    
    grot.actContainer.addAct(act);
    grot.requestFocusInWindow();
  }
}
